package edu.thu.thss.yxy.gui;

import java.util.Vector;
import javax.swing.table.AbstractTableModel;

import edu.thu.thss.yxy.sip.CallPeer;

class CallPeersTableModel extends AbstractTableModel {
	private static final int NAME_COLUMN_INDEX = 0;
	private static final int ADDRESS_COLUMN_INDEX = 1;
	private static final int CALL_STATUS_COLUMN_INDEX = 2;
	private final String[] columnNames = { "Name", "Address", "Call Status" };
	private Vector<CallPeer> callPeers = new Vector<CallPeer>();

	public int getColumnCount() {
		return columnNames.length;
	}

	public int getRowCount() {
		return callPeers.size();
	}

	public String getColumnName(int col) {
		return columnNames[col];
	}

	public Object getValueAt(int row, int col) {
		Object res;
		if (row >= callPeers.size())
			return "";
		CallPeer callPeer = (CallPeer) callPeers.get(row);
		switch (col) {
		case NAME_COLUMN_INDEX:
			res = callPeer.getDisplayName();
			break;
		case ADDRESS_COLUMN_INDEX:
			res = callPeer.getAddress();
			break;
		case CALL_STATUS_COLUMN_INDEX:
			res = callPeer.getState();
			break;
		default:
			throw new IndexOutOfBoundsException("There is no column "
					+ new Integer(col).toString());
		}

		return res == null ? "" : res;
	}

	/*
	 * JTable uses this method to determine the default renderer/ editor for
	 * each cell. If we didn't implement this method, then the last column would
	 * contain text ("true"/"false"), rather than a check box.
	 */
	public Class<?> getColumnClass(int c) {
		return getValueAt(0, c).getClass();
	}

	/*
	 * Don't need to implement this method unless your table's editable.
	 */
	public boolean isCellEditable(int row, int col) {
		return false;
	}

	public void printDebugData() {
		int numRows = getRowCount();
		int numCols = getColumnCount();
		for (int i = 0; i < numRows; i++) {
			System.out.print("    row " + i + ":");
			for (int j = 0; j < numCols; j++) {
				System.out.print("  " + getValueAt(i, j));
			}
			System.out.println();
		}
		System.out.println("--------------------------");
	}

	void addCallPeer(CallPeer callPeer) {
		callPeers.addElement(callPeer);
		fireTableRowsInserted(callPeers.size() - 1, callPeers.size() - 1);
	}

	void removeInterlocutor(int id) {
		int i = 0;
		for (CallPeer callPeer : callPeers) {
			if (callPeer.getPeerID().equals(String.valueOf(id))) {
				callPeers.remove(callPeer);
				fireTableRowsDeleted(i, i);
			}
			i++;
		}
	}

	CallPeer getCallPeerAt(int row) {
		return ((CallPeer) callPeers.get(row));
	}

	private void updateInterlocutorStatus(int interID) {
		int index = findIndex(interID);
		fireTableRowsUpdated(index, index);
	}

	int findIndex(int id) {
		for (int i = 0; i < callPeers.size(); i++) {
			if (((CallPeer) callPeers.get(i)).getPeerID().equals(
					String.valueOf(id)))
				return i;
		}
		return -1;
	}

	// ----------------------------- GUI Callback ---------------------------
	public void update(CallPeer callPeer) {
		updateInterlocutorStatus(Integer.parseInt(callPeer.getPeerID()));
	}

	public void remove(CallPeer callPeer) {
		removeInterlocutor(Integer.parseInt(callPeer.getPeerID()));
	}
}